﻿using System.Diagnostics;
using System.Text;
using LuckyShell.ShellOrders;
using LuckyShell.ShellValues;

namespace LuckyShell;

public class VariateManager
{
    private Dictionary<string, object> Variate { get; set; } = new();

    private Dictionary<string, FuncOrder> Functions { get; set; } = new();
    private Process Process { get; set; } = new();

    public VariateManager()
    {
        Process.StartInfo.FileName = OperatingSystem.IsWindows() ? "cmd.exe" : "/bin/bash";
        Process.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动
        Process.StartInfo.RedirectStandardInput = true; //接受来自调用程序的输入信息
        Process.StartInfo.RedirectStandardOutput = true; //由调用程序获取输出信息
        Process.StartInfo.RedirectStandardError = true; //重定向标准错误输出
        Process.StartInfo.StandardOutputEncoding = Encoding.UTF8;
    }

    public void SetValue(IdentifierValue id, object value)
    {
        if (value is ShellTree) throw new Exception($"Variate {id.IdentifierName} dot`t set Shell Data");
        if (!Variate.TryAdd(id.IdentifierName, value))
            Variate[id.IdentifierName] = value;
    }

    public object GetValue(IdentifierValue id)
    {
        Variate.TryGetValue(id.IdentifierName, out var value);
        if (value is null) throw new Exception($"Variate {id.IdentifierName} has not Value");
        return value;
    }

    public void SetValue(string funcName, FuncOrder order)
    {
        if (!Functions.TryAdd(funcName, order))
            Functions[funcName] = order;
    }

    public FuncOrder GetValue(string funcName)
    {
        Functions.TryGetValue(funcName, out var value);
        if (value is null) throw new Exception($"Function {funcName} has not Value");
        return value;
    }

    public void Order(string o)
    {
        Console.WriteLine(OrderString(o));
    }

    public string OrderString(string o)
    {
        Process.Start();
        Process.StandardInput.WriteLine(o); //指令
        Process.StandardInput.Close();

        var array = Process.StandardOutput.ReadToEnd().Split(Environment.NewLine);
        Process.Close();
        var builder = new StringBuilder();
        for (var i = 0; i < array.Length - 1; i++)
        {
            if (OperatingSystem.IsWindows())
            {
                if (i < 4) continue;
            }
            else
            {
                if (i == 0) continue;
            }

            if (string.IsNullOrEmpty(array[i])) continue;
            builder.Append(array[i] + Environment.NewLine);
        }

        return builder.ToString();
    }

    private List<int> Children { get; set; } = new();
    public void AddChildren() => Children.Add(Variate.Count - 1);

    public void RemoveChildren()
    {
        var a = Children.Last();
        Children.RemoveAt(Children.Count - 1);
        var b = Variate.Keys.ToArray();
        for (var i = Variate.Count - 1; i > a; i--)
        {
            var c = b[i];
            Variate.Remove(c);
        }
    }

    public void Delete(string id)
    {
        if (!Variate.Remove(id, out _))
            throw new Exception($"Not Fount Id {id}");
    }
}